#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#include <hi_ext_util.h> 
#include "wifi_apd_setup.h"

#define APD_SSID_PFX 	"HiSpark_"
#define APD_IF_NAME 	"ap0"
#define APD_IF_IP		"192.168.150.150"
#define APD_CFG_FILE	"/etc/Wireless/hostapd.conf"
#define APD_CTRL_PATH	"/var/hostapd"
#define APD_PID_FILE	"/var/run/hostapd_ap0.pid"

#define UDHCPD_CFG_FILE	 "/etc/Wireless/udhcpd.conf"
#define UDHCPD_PID_FILE	 "/var/run/udhcpd_ap0.pid"

static char g_ssid[TINY_BUF_SIZE] = "";

int ApdInit(void)
{
	uint8_t mac[MAC_BYTE_SIZE] = { 0 };
	char macSfx[TINY_BUF_SIZE] = "";
	FILE *file = NULL;
	pid_t pid;
	int ret;
	
	// 获取mac地址后2byte的hex string表示
	ret = IfGetMacBytes(APD_IF_NAME, mac, sizeof(mac));
	HI_EXP_RET(ret < 0, ret, "get mac addr of '%s' FAIL\n", APD_IF_NAME);
	ret = snprintf_s(macSfx, sizeof(macSfx), sizeof(macSfx) - 1,
		"%02X%02X%02X",(int)mac[3], (int)mac[4], (int)mac[5]);
	assert(ret > 0);

	// 生成SSID
	ret = snprintf_s(g_ssid, sizeof(g_ssid), sizeof(g_ssid) - 1, "%s%s", APD_SSID_PFX, macSfx);
	assert(ret > 0);
	
	// 创建hostapd需要的配置文件，存入fs
	LOGI("WIFI: write '%s' ...\n", APD_CFG_FILE);
	file = fopen(APD_CFG_FILE, "wt");
	assert(file);
	ret = fprintf(file,
		"interface=%s\n"
		"driver=nl80211\n"
		"ctrl_interface=%s\n"
		"ssid=%s\n"
		"channel=6\n"
		"hw_mode=g\n"
		"ieee80211n=1\n"
		"auth_algs=1\n"
		"ht_capab=[SHORT-GI-20]\n",
		APD_IF_NAME, APD_CTRL_PATH, g_ssid);
	assert(ret > -1);
	fclose(file);
	file = NULL;
	
	// 设置IP
	LOGI("WIFI: set wlan0 ip to '%s' ...\n", APD_IF_IP);
	ret = IfSetIpStr(APD_IF_NAME, APD_IF_IP);
	
	// 启动hostapd服务
	printf("@@@ start hostapd ...\n");
	pid = ForkAndExeclp("hostapd", "hostapd", "-B", "-P", APD_PID_FILE, APD_CFG_FILE, NULL);
	assert(pid>0);
	
	printf("@@@ start udhcpd ...\n");
	pid = ForkAndExeclp("udhcpd", "udhcpd", UDHCPD_CFG_FILE, NULL);
	assert(pid>0);
	return 0;
}


int ApdExit(void)
{
	KillByPidFile(UDHCPD_PID_FILE, true, "udhcpd");
	KillByPidFile(APD_PID_FILE, true, "hostapd");
	g_ssid[0] = 0;
	return 0;
}
	
const char* ApdSsid(void)
{
	return g_ssid;
}

